package ar.com.utn.openqsb.lip.ui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.List;

import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFormattedTextField;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;

import org.jvnet.lafwidget.LafWidget;

import ar.com.utn.openqsb.lip.core.Constraint;
import ar.com.utn.openqsb.lip.core.Exercise;
import ar.com.utn.openqsb.lip.core.LIPException;
import ar.com.utn.openqsb.lip.core.LIPManager;
import ar.com.utn.openqsb.lip.core.SimplexResult;
import ar.com.utn.openqsb.lip.core.Constraint.Relation;

public class ExerciseFrame extends JInternalFrame
{

    private static final long serialVersionUID = 1L;

    private static int openFrameCount = 0;

    private static final int xOffset = 30, yOffset = 30;

    private String exerciseId;

    private JFileChooser fileChooser;

    private JTabbedPane tabs;

    private ExerciseDataPanel data;

    private ExerciseResultPanel result;

    public ExerciseFrame(String exerciseId)
    {

        fileChooser = new JFileChooser();

        this.exerciseId = exerciseId;
        Exercise descriptor = LIPManager.getInstance().get(this.exerciseId);

        // Set the window's location.
        setLocation(xOffset * openFrameCount, yOffset * openFrameCount);
        openFrameCount++;

        // create toolbar
        ToolBarFactory.createToolBar(this);

        // create tab panels
        setTitle(descriptor.getName());
        setPreferredSize(new Dimension(600, 400));
        setResizable(true);
        setClosable(true);
        setMaximizable(true);
        setIconifiable(true);
        tabs = new JTabbedPane();
        tabs.putClientProperty(LafWidget.TABBED_PANE_PREVIEW_PAINTER, new TabPreviewPainter());
        data = new ExerciseDataPanel(descriptor);
        tabs.addTab(descriptor.getName() + " - Data", null, new JScrollPane(data));
        add(tabs, BorderLayout.CENTER);
        pack();
    }

    public void launch()
    {
        setVisible(true);
    }

    public void refresh()
    {
        try
        {
            Exercise descriptor = LIPManager.getInstance().get(this.exerciseId);
            // set objective coefficients
            List<JFormattedTextField> objectiveCoefficients = data.getObjectiveCoefficients();
            for (int i = 0; i < objectiveCoefficients.size(); i++)
            {
                String value = objectiveCoefficients.get(i).getText().trim().equals("") ? "0" : objectiveCoefficients.get(i).getText().trim();
                descriptor.setObjectiveCoefficient(i, DecimalFormat.getInstance().parse(value).doubleValue());
            }

            // set objective constant term
            String cterm = data.getConstantTerm().getText().trim().equals("") ? "0" : data.getConstantTerm().getText().trim();
            descriptor.setObjectiveConstantTerm(DecimalFormat.getInstance().parse(cterm).doubleValue());

            // set constraint
            List<List<JFormattedTextField>> constraintCoefficients = data.getConstraintCoefficients();
            List<JComboBox> relations = data.getRelations();
            List<JFormattedTextField> rightValues = data.getRightValues();
            for (int i = 0; i < constraintCoefficients.size(); i++)
            {
                Constraint constraint = new Constraint(descriptor.getNumVars());
                descriptor.setConstraintCoefficient(i, constraint);
                constraint.setRelation(((Relation) relations.get(i).getSelectedItem()));
                String rightValue = rightValues.get(i).getText().equals("") ? "0" : rightValues.get(i).getText();
                constraint.setRightValue(DecimalFormat.getInstance().parse(rightValue).doubleValue());
                for (int j = 0; j < constraintCoefficients.get(i).size(); j++)
                {
                    String value = constraintCoefficients.get(i).get(j).getText().equals("") ? "0" : constraintCoefficients.get(i).get(j).getText();
                    constraint.setCoefficient(j, DecimalFormat.getInstance().parse(value).doubleValue());
                }
            }
        } catch (ParseException e)
        {
            e.printStackTrace();
        }
    }

    public void solve()
    {
        refresh();
        Exercise descriptor = LIPManager.getInstance().get(this.exerciseId);
        SimplexResult simplexResult = LIPManager.getInstance().solve(descriptor);
        result = new ExerciseResultPanel(simplexResult);
        try
        {
            tabs.remove(1);
        } catch (IndexOutOfBoundsException e)
        {
            // Nothing to do, the tab already exist.
        }
        tabs.addTab(descriptor.getName() + " - Result", null, new JScrollPane(result));
        tabs.setSelectedIndex(1);
    }

    public void chart()
    {
        refresh();
    }

    public boolean save()
    {
        boolean result = false;
        refresh();
        int rVal = fileChooser.showSaveDialog(this);
        if (rVal == JFileChooser.APPROVE_OPTION)
        {
            try
            {
                LIPManager.getInstance().save(this.exerciseId, fileChooser.getSelectedFile());
                result = true;
            } catch (LIPException e)
            {
                JOptionPane.showMessageDialog(this, e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
            }
        } else
        {
            System.out.println("You pressed cancel");
        }
        return result;
    }

    @Override
    public void doDefaultCloseAction()
    {
        int response = JOptionPane.showConfirmDialog(null, "Do you want to save the current exercise?", "Save File", JOptionPane.YES_NO_OPTION);
        switch (response)
        {
        case JOptionPane.YES_OPTION:
            if (save())
            {
                super.doDefaultCloseAction();
                LIPManager.getInstance().remove(this.exerciseId);
            }
            break;
        case JOptionPane.NO_OPTION:
            super.doDefaultCloseAction();
            LIPManager.getInstance().remove(this.exerciseId);
            break;
        case JOptionPane.CLOSED_OPTION:
            break;
        }

    }

}
